import com.lmax.disruptor.dsl.Disruptor;
import config.DisruptorProperties;
import factory.DisruptorFactory;
import factory.EventThreadFactory;
import handler.ProducerHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;

@Slf4j
public abstract class DisruptorProcessorTemplate<T> {

    @Autowired
    private DisruptorProperties disruptorProperties;
    @Autowired
    private EventThreadFactory eventThreadFactory;

    protected Disruptor disruptor;

    @PostConstruct
    public void init() throws Exception {
        log.info("DisruptorProcessorTemplate init");
        //1.获取disruptor实例
        DisruptorFactory<T> disruptorFactory = new DisruptorFactory<>(disruptorProperties,eventThreadFactory);
        disruptor = disruptorFactory.getInstance();
        //2.consumer具体实现,需要继承AbstractConsumerEventHandler实现子类
        consumerProcessor(disruptor);
        //3.启动disruptor
        disruptor.start();
        log.info("DisruptorProcessorTemplate disruptor start");
    }

    public void push() throws Exception{
        //4.生产者具体实现
        T t = producerProcessor();
        log.info("DisruptorProcessorTemplate push {}",t.toString());
        ProducerHandler<T> producerHandler = new ProducerHandler<T>(disruptor.getRingBuffer());
        producerHandler.onData(t);
    }

    public void shutdown(){
        log.info("DisruptorProcessorTemplate is shutdown");
        if(disruptor!=null){
            disruptor.shutdown();
        }
    }

    protected abstract <T> T producerProcessor() throws Exception;

    protected abstract void consumerProcessor(Disruptor disruptor) throws Exception;

}
